home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_52 / arped.ma < prev    next >
Text File  |  1995-01-01  |  8KB  |  358 lines

  1. #
  2. # stochastic arp editor
  3. #
  4. # edit a stochastic arpeggiator matrix while playing it
  5. #
  6.  
  7. @include c:\mbin\mh\wind.mh
  8. @include c:\mbin\mh\actions.mh
  9.  
  10. #
  11. # stochastic array
  12. #
  13. # Probability 0..100
  14. # Last note means if the last note was X, then
  15. # choose this note. If last note column is the
  16. # new note column set back one. This increases
  17. # the odds of playing notes in the order given
  18. # (column-wise) of the next note array.
  19. #
  20. TRUE = 1
  21. FALSE = 0
  22.  
  23. MAXARP = 100
  24.  
  25. THISNOTE = 0
  26. THISTIME = 1
  27. NEXTNOTE = 2
  28. NEXTPROB = 3
  29.  
  30. uchar arptable[MAXARP][4] = {
  31.     LLA,    e,    LC,    70,
  32.     LC,    e,    LB,    50,
  33.     D#,    e,    LA,    70,
  34.     LA,    e,    LB,    70,
  35.     LB,    e,    C,    100,
  36.     C,    e,    F#,    50,
  37.     F#,    e,    G,    100,
  38.     G,    s,    A,    50,
  39.     G,    s,    D,    25,
  40.     G,    s,    C,    25,
  41.     G,    s,    E,    25,
  42.     A,    s,    B,    0,
  43.     B,    t,    HD,    100,
  44.     HD,    t,    HE,    100,
  45.     HE,    t,    HF#,    100,
  46.     HF#,    q,    HE,    100 
  47. }
  48.  
  49. # how long in quarter notes to do stochArp call
  50. uchar howlong[1] = {
  51. 4
  52. }
  53.  
  54. # enable/disable loop mode - continous loop play
  55. # of action
  56. #
  57. LOOPOFF = 0
  58. LOOP    = 1
  59.  
  60. # play action once, do nothing, print action in ascii file
  61. # should add binary save/load.
  62. BREAD = 0
  63. BWRITE = 1
  64. PLAY = 2
  65. PRINT = 3
  66. ZILCH = 4  # no command
  67.  
  68. uchar loopOn[1]
  69. uchar editCom[1]
  70.  
  71. NOCOLS = 4
  72. LSIZE = 5   # max label size
  73. FSIZE = 5   # field size 
  74.  
  75. riff printArp()
  76.     int fd
  77.     int i
  78.     int rowcount
  79.  
  80.     fd = open("arp.ma",3)
  81.  
  82.     for ( i = 0; i < MAXARP; i++)
  83.         if (arptable[i][0] == 0)
  84.             break
  85.         end
  86.     end
  87.     rowcount = i
  88.  
  89.     void fprintf(fd, "uchar arp[%d+1][4] = {\n",rowcount)
  90.     for ( i = 0; i < MAXARP; i++)
  91.         if (arptable[i][0] == 0)
  92.             break
  93.         end
  94.         void fprintf(fd, "\t%n,\t%t,\t%n,\t%d,\n",arptable[i][0],arptable[i][1], arptable[i][2], arptable[i][3])
  95.     end
  96.     void fprintf(fd,"\t0\n")
  97.     void fprintf(fd, "}\n")
  98.     void close(fd)
  99. end
  100.  
  101. # action window handle
  102. int arpwd
  103.  
  104. riff openArpWindow()
  105.     # put up action window first so that it gets
  106.     # cursor
  107.      arpwd = inputMWindow(WTABLE, 0, 0, 20, NOCOLS*FSIZE+2+LSIZE, "stocharp", 1, 5, 4, &arptable)
  108.     void windowControl(arpwd, NOTETRANSLATION, 0, 0)
  109.     void windowControl(arpwd, TIMETRANSLATION, 1, 0)
  110.     void windowControl(arpwd, NOTETRANSLATION, 2, 0)
  111. end
  112.  
  113.  
  114. riff reopenActionWindow()
  115.     void closeWindow(arpwd)
  116.     void openArpWindow()
  117. end
  118.  
  119. # default string name of action file
  120. uchar arpfile[20]={
  121. 'a','r','p','.','b',0
  122. }
  123.  
  124.  
  125. # write action array out as binary file
  126. riff writeBinary()
  127.     int fd
  128.  
  129.     # open the file
  130.     fd = open(&arpfile, 3)
  131.     # write the acts array
  132.     void printf("writing action file...")
  133.     void write(fd, &arptable[0], MAXARP * 4)
  134.     void close(fd)
  135. end
  136.  
  137. # read action array back in as binary file and
  138. # update display
  139. riff readBinary()
  140.     int fd
  141.     int count
  142.  
  143.     fd = open(&arpfile, 0)
  144.     void read(fd, &arptable[0], MAXARP * 4)
  145.     void close(fd)
  146.     void reopenActionWindow()
  147. end
  148.  
  149.  
  150. riff openWindows()
  151.     int wd
  152.  
  153.     void openArpWindow()
  154.     # define window for edit/play commands
  155.     wd = inputWindow(WDEFINE, 9, 40, 12, 50, "loop", 2, 0, 0, &loopOn)
  156.     void windowLabel(wd, "off", 0)
  157.     void windowLabel(wd, "loop", 1)
  158.     wd = inputWindow(WDEFINE, 13, 40, 18, 50, "command", 4, 0, 0, &editCom)
  159.     void windowLabel(wd, "bread", 0)
  160.     void windowLabel(wd, "bwrite", 1)
  161.     void windowLabel(wd, "play", 2)
  162.     void windowLabel(wd, "print", 3)
  163.     wd = inputWindow(WNUMERIC, 19, 40, 21, 50, "arptime", 4, 5, 1, &howlong)
  164.     void windowLabel(wd, "q's:", 0)
  165.     # voicelist and rcc windows
  166.     void mosWindow(WVCO,5,40)
  167.     void mosWindow(WRCC,0,40)
  168.     # debug window
  169.     void outputWindow(WDEBUG,10,51,24,79,"printf") # halfway
  170.     wd = inputWindow(WSTRING, 21, 0, 0, 0, "enter arpfile ", 1, 1, 19, &arpfile)
  171. end
  172.  
  173. #
  174. # algorithm:
  175. #
  176. #    play first
  177. #    then make probability transition
  178. #
  179. int lastindex = 0
  180. riff stochArp(matrix m, col, maxtime, startover)
  181. # matrix m - pointer to 2d uchar array
  182. # col - size of column of array
  183. # maxtime - maximum time arp should run
  184. # startover - don't use lastindex, set index to 0
  185.     int i        # general loop index
  186.     int curindex    # array index for playing
  187.     int nextindex   # next array index after search
  188.     int rval    # rand no.
  189.     int curtime    # how much time taken so far
  190.     int remtime    # how much time before stocharp returns
  191.     int nexttime    # time request taken from stoch array
  192.     int row   # no of rows before 0 note in array
  193.     int candidate    # candidate note to search array for
  194.     int foundit     # flag indicating if candidate was found
  195.  
  196.     # find end of stoch arp, 1st 0 or out of rows
  197.     # indicates end.
  198.     for ( i = 0; i < MAXARP; i++)
  199.         if (m[i][0] == 0)
  200.             break
  201.         end
  202.     end
  203.     # put index in row to set array size
  204.     row = i
  205.     curtime = 0
  206.     if (startover == 1)
  207.         lastindex = 0
  208.     end
  209.     curindex = lastindex
  210.  
  211.     # loop thru while there is time
  212.     for (curtime = 0;;)
  213.  
  214.         # PLAY THE NOTE FIRST
  215.         # play the note
  216.         remtime = maxtime - curtime
  217. void printf("rem %d, max %d, cur %d",remtime,maxtime,curtime)
  218.         nexttime = m[curindex][THISTIME]
  219.         # if remaining event time is less than
  220.         # requested time, trucate request so
  221.         # that overall SPAN passed in is exact
  222.         # this also means we are about to return.
  223.         if (remtime < nexttime )
  224.             nexttime = remtime
  225.             rval = mrandrange(1,100)
  226.             if (rval < 33)
  227. void printf("tie %t",nexttime)
  228.                 tie nexttime
  229.             else if (rval < 66)
  230.                 rest nexttime
  231. void printf("rest %t",nexttime)
  232.             else
  233. void printf("[%d]:%n %t",curindex, m[curindex][0], nexttime)
  234.                  m[curindex][0] nexttime mrandrange(70,125)
  235.             end
  236.         else
  237. void printf("[%d]:%n %t",curindex, m[curindex][0], nexttime)
  238.              m[curindex][0] nexttime mrandrange(70,125)
  239.         end
  240.         # update elapsed time
  241.         curtime = curtime + nexttime
  242.         # if elapsed time exceeds or is the same than
  243.         # maxtime, quit
  244.         if (curtime >= maxtime)
  245.             return(1) 
  246.         end
  247.  
  248.         # NOW CHOOSE WHERE TO GO TO
  249.  
  250.         # choose nextnote according to probability.
  251.         # if probability match occurs we SEARCH thru
  252.         # the array for the next note (we play it if we find it)
  253.         # if we don't find it, we just take the next iterative
  254.         # note in the array to play
  255.         candidate = m[curindex][NEXTNOTE]
  256.          
  257.         foundit = FALSE
  258.         rval = mrandrange(0,100)
  259.  
  260.         # set nextindex to next note which is where we go
  261.         # if probability match fails
  262.         nextindex = curindex + 1
  263.         # logical wrap
  264.         if ( nextindex >= row)
  265.             nextindex = 0
  266.         end
  267.         # if prob match succeeds
  268.         if ( rval < m[curindex][NEXTPROB] )
  269.             # search through remaining array from
  270.             # current position to end FIRST, this
  271.             # helps us to advance down
  272.             for ( i = curindex; i < row; i++)
  273.                 if (m[i][THISNOTE] == candidate)
  274.                     foundit = TRUE
  275.                     nextindex = i
  276.                     break
  277.                 end
  278.             end
  279.             # if search failed, search from beginning to current.
  280.             if (foundit == FALSE)
  281.                 for ( i = 0; i < curindex; i++)
  282.                     if (m[i][THISNOTE] == candidate) 
  283.                         foundit = TRUE
  284.                         nextindex = i
  285.                         break
  286.                     end
  287.                 end
  288.             end
  289.         end
  290.         # nextindex indicates WHERE we want to advance to
  291.         # lastindex is stored in case we are called again
  292.         lastindex = nextindex
  293.         # curindex is what we use for playing the note
  294.         curindex = nextindex
  295.     end
  296.     return(1)
  297. end
  298.  
  299. riff doStochArp()
  300.     void stochArp(&arptable, 4, howlong[0] * q, 1)
  301. end
  302.  
  303. # work from edit/play DEFINE carrying out commands.
  304. #
  305.  
  306. vco actedit()
  307.     void openWindows()
  308.  
  309.     # poll for command change
  310.     editCom[0] = ZILCH
  311.     for(;;)
  312.         switch(editCom[0])
  313.         case PLAY:
  314.             void doStochArp()
  315.             editCom[0] = ZILCH
  316.             end
  317.         case PRINT:
  318.             void printArp()
  319.             editCom[0] = ZILCH
  320.             end
  321.         case BREAD:
  322.             void readBinary()
  323.             editCom[0] = ZILCH
  324.             end
  325.         case BWRITE:
  326.             void writeBinary()
  327.             editCom[0] = ZILCH
  328.             end
  329.         end
  330.         rest 1
  331.     end
  332. end
  333.  
  334. # play action in LOOP mode
  335. vco playit
  336.     int lastCom
  337.     int doit
  338.     loopOn[0] = LOOPOFF
  339.     lastCom   = LOOPOFF
  340.     doit = 0
  341.     for(;;)
  342.         if (loopOn[0] != lastCom)
  343.             lastCom = loopOn[0]
  344.             if (loopOn[0] == LOOPOFF)
  345.                 doit = 0
  346.             else
  347.                 doit = 1
  348.             end
  349.         end
  350.         if (doit)
  351.             void doStochArp()
  352.         end
  353.         rest    1
  354.     end
  355. end
  356.  
  357.  
  358.